#This change is just to see if Subversion is set up right.

import FRCParser
import re
import time
import cgi
from django.utils import simplejson
from xml.dom.minidom import Document
from string import Template
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import urlfetch
from google.appengine.api import memcache

default_year = "2009"

rankings_cache = 60
awards_cache = 600
schedule_cache = 60
results_cache = 60

#Stores the event codes and their common names.
event_codes = {
"arizona":"az",
"az":"az",
"autodesk oregon":"or",
"or":"or",
"bae granite state":"nh",
"nh":"nh",
"bayou":"la",
"la":"la",
"boilermaker":"in",
"in":"in",
"boston":"ma",
"ma":"ma",
"buckeye":"oh",
"oh":"oh",
"chesapeake":"md",
"ma":"ma",
"colorado":"co",
"co":"co",
"connecticut":"ct",
"ct":"ct",
"dallas":"da",
"da":"da",
"finger lakes":"roc",
"roc":"roc",
"greater kansas city":"kc",
"kc":"kc",
"greater toronto":"on",
"on":"on",
"hawaii":"hi",
"hi":"hi",
"isreal":"is",
"is":"is",
"las vegas":"nv",
"nv":"nv",
"lone star":"tx",
"tx":"tx",
"los angeles":"ca",
"ca":"ca",
"microsoft seattle":"wa",
"wa":"wa",
"midwest":"il",
"il":"il",
"minnesota 10000 lakes":"mn",
"mn":"mn",
"minnesota north star":"mn2",
"mn2":"mn2",
"new jersey":"nj",
"nj":"nj",
"new york city":"ny",
"ny":"ny",
"north carolina":"nc",
"nc":"nc",
"oklahoma":"ok",
"ok":"ok",
"palmetto":"ga",
"ga":"ga",
"pittsburgh":"pit",
"pit":"pit",
"sacramento":"sac",
"sac":"sac",
"san diego":"sdc",
"sdc":"sdc",
"sbpli long island":"li",
"li":"li",
"silicon valley":"sj",
"sj":"sj",
"st. louis":"mo",
"mo":"mo",
"utah":"ut",
"ut":"ut",
"virginia":"va",
"va":"va",
"washington dc":"dc",
"dc":"dc",
"waterloo":"wat",
"wat":"wat",
"wisconsin":"wi",
"wi":"wi",
"wpi":"wor",
"wor":"wor",
"ann arbor":"wc",
"wc":"wc",
"cass tech":"dt1",
"dt1":"dt1",
"detroit":"dt",
"dt":"dt",
"kettering":"gg",
"gg":"gg",
"traverse city":"gt",
"gt":"gt",
"troy":"oc",
"oc":"oc",
"west michigan":"mi",
"mi":"mi",
"michigan state championship":"gl",
"gl":"gl",
"championship":"cmp",
"cmp":"cmp",
"archimedes":"arc",
"arc":"arc",
"curie":"cur",
"cur":"cur",
"galileo":"gal",
"gal":"gal",
"newton":"new",
"new":"new",
"einstein":"ein",
"ein":"ein"
}


what = {
"schedule":{"url":"http://www2.usfirst.org/${Year}comp/events/${Event}/schedule${When_Short}.html", "Table":"${When} Schedule","Index_Column":"Match","Skip_Title":False,"Custom_Title":None,"As_Int":True,"Require_When":True,"Cache_Time":schedule_cache},
"rankings":{"url":"http://www2.usfirst.org/${Year}comp/events/${Event}/rankings.html", "Table":"2","Index_Column":"Rank","Skip_Title":True,"Custom_Title":None,"As_Int":True,"Require_When":False,"Cache_Time":rankings_cache},
"awards":{"url":"http://www2.usfirst.org/${Year}comp/events/${Event}/awards.html", "Table":"2","Index_Column":"Award","Skip_Title":True,"Custom_Title":None,"As_Int":False,"Require_When":False,"Cache_Time":awards_cache},
"results":{"url":"http://www2.usfirst.org/${Year}comp/events/${Event}/matchresults.html", "Table":"${When} Matches","Index_Column":"Match","Skip_Title":False,"Custom_Title":None,"As_Int":True,"Require_When":True,"Cache_Time":results_cache}
}

when = ["qualification","elimination"]
format = ["xml","json","human"]
year = ["2009","2008","2007"]


what_error = "You did not specify what you wanted.<br/>"
event_error = "You did not specify an event.<br/>"
def parse_request(handler):
  request = {}
  args = handler.request.path.lower().split("/")
  have_year = False
  have_event = False
  have_what = False
  have_when = False
  need_when = False
  have_format = False
  index = 1
  request["When"] = when[0]
  request["Year"] = year[0]
  request["Format"] = format[0]
  request["What"] = what.keys()[0]
  for el in args:
    if el in event_codes:
      request["Event"] = event_codes[el]
      have_event = True
    if el in year:
			request["Year"] = el
			have_year = True
    if el in what.keys() and not have_what:
      request["What"] = el
      need_when = what[el]["Require_When"]
      have_what = True
    if el in when and not have_when:
      request["When"] = el
      request["When_Short"] = el[:4]
      have_when = True
    if el in format and not have_format:
      request["Format"] = el
      have_format = True
    if len(el.split("-"))>1:
      request["Begin"] = el.split("-")[0]
      request["End"] = el.split("-")[1]
      if request["Begin"] == "":
        request["Begin"] = None
      if request["End"] == "":
        request["End"] = None
      request["Split"] = True
  if (need_when and not have_when) and not (have_year and have_event and have_what) :
    request["Error"] = True
  return request

def slice(data,beg = None,end = None):
  data2 = {}
  if beg != None:
    beg = int(beg) - 1
  if beg == None:
    beg = 0
  if end != None:
    end = int(end)
  if beg < 0:
    beg = 0
  if end <= beg:
    end = beg
  for el in data.keys()[beg:end]:
    data2[el] = data[el]
  return data2

def XML_escape(value):
  return re.sub(" ","_",str(value))

def remove_tags(value):
  return re.sub("&nbsp;","",re.sub("<.*?>","",value))

class FRCFeed(webapp.RequestHandler):

 
  def display_index(self):
    string = "Please use frcfeed.appspot.com/[Year]/[Event]/[Qualification or Elimination]/[Awards or Schedule or Rankings or Results]"
    self.response.out.write(string)
  
  def generate_response(self, request):
    Memcache_Name = Template("${Year} ${Event} ${When} ${What}").substitute(request)
    data = memcache.get(Memcache_Name)
    What_Dictionary = what[request["What"]]
    Index_Column = What_Dictionary["Index_Column"]
    if data == None:
      url = Template(What_Dictionary["url"]).substitute(request)
      HTML = urlfetch.fetch(url).content
      Skip_Title = What_Dictionary["Skip_Title"]
      As_Int = What_Dictionary["As_Int"]
      data = FRCParser.parse(HTML,Index_Column,Skip_Title,As_Int)
      memcache.add(Memcache_Name,data,What_Dictionary["Cache_Time"])
    Table_Name = Template(What_Dictionary["Table"]).substitute(request).title()
    if Table_Name.isdigit():
      Table_Name= int(Table_Name)
    if "Split" in request and What_Dictionary["As_Int"]:
      data[Table_Name] = slice(data[Table_Name],request["Begin"],request["End"])
    self.print_response(request,data[Table_Name],Index_Column)
  
  def print_response(self,request,data,indexValue):
    if request["Format"] == "json":
      self.response.out.write(re.sub("<.*?>","",simplejson.dumps(data)))
    if request["Format"] == "xml":
      doc = Document()
      Event = doc.createElement("Event")
      doc.appendChild(Event)
      Sorted_Keys = data.keys()
      Sorted_Keys.sort()
      for element in Sorted_Keys:
        xml_element = doc.createElement(indexValue)
        xml_element.setAttribute("id",XML_escape(element))
        Event.appendChild(xml_element)
        for content in data[element].keys():
          xml_content = doc.createElement(XML_escape(content))
          info = doc.createTextNode(str(data[element][content]))
          xml_content.appendChild(info)
          xml_element.appendChild(xml_content)
      self.response.out.write(doc.toprettyxml(indent = "  "))
    if request["Format"] == "human":
      doc = Document()
      Event = doc.createElement("table")
      doc.appendChild(Event)
      Sorted_Keys = data.keys()
      Sorted_Keys.sort()
      for element in Sorted_Keys:
        xml_element = doc.createElement("tr")
        xml_element.setAttribute("id",XML_escape(element))
        Event.appendChild(xml_element)
        for content in data[element].keys():
          xml_content = doc.createElement("td")
          info = doc.createTextNode(str(data[element][content]))
          xml_content.appendChild(info)
          xml_element.appendChild(xml_content)
      self.response.out.write(doc.toprettyxml(indent = "  "))   
  
  
  def get(self):
    request = parse_request(self)
    try:
      self.generate_response(request)
    except:
      self.display_index()
  
application = webapp.WSGIApplication(
                                     [('.*', FRCFeed)],debug=True)
def main():
  try:
    run_wsgi_app(application)
  except:
    pass

if __name__ == "__main__":
  main()